#ifndef DIFFTOOL_H
#define DIFFTOOL_H

#include "MainObject.h"
#include "CmpMngr.h"
#include <algorithm>
#include <sstream>
#include <time.h>

//Diff Functionality Defines
#define BASELINE_INF1 "fileListA.txt"
#define BASELINE_INF2 "fileListB.txt"
#define DIFF_OUTFILE "outfile_diff_results.txt"
#define DIFF_OUTFILE_CSV "outfile_diff_results.csv"
#define MATCH_PAIRS_OUTFILE "MatchedPairs.txt"

#define MAX_MISMATCH_COST	10000

#define BAR_S	"-"

/*
#define DIFFED_BASELINE "tmp_diff_files.txt"
#define CC_BASELINE_OUTFILE "codecount_outfileListAB.txt"
#define CC_BASELINEA_OUTFILE "codecount_outfileListA.txt"
#define CC_BASELINEB_OUTFILE "codecount_outfileListB.txt"
#define CC_DIFFERENCES_OUTFILE "codecount_outfileDifferences.txt"
#define UNUSED_OUTFILE "outfile_unusedInputFiles.txt"
*/

class DiffTool: public MainObject
{
	class resultStruct
	{
		public:
			int addedLines;
			int deletedLines;
			int modifiedLines;
			int unmodifiedLines;
			resultStruct() { addedLines = deletedLines = modifiedLines = unmodifiedLines = 0; }
	};

	private:
		//Diff Baseline Files
		string BaselineFileName1;
		string BaselineFileName2;
		double match_threshold;
		bool use_SLOC;
		// ------------------   Duplication Modification -----------------------
		// Flag to indicate if the file names are to be read from command line specifications 
		// or from the input files.
		bool use_CommandLine;

		//Summary Results
		int total_addedLines;
		int total_deletedLines;
		int total_modifiedLines;
		int total_unmodifiedLines;
		int dup_addedLines;
		int dup_deletedLines;
		int dup_modifiedLines;
		int dup_unmodifiedLines;

		void parse_commandLine(int argc, char *argv[]);
		int handleReadInputFiles();
		typedef pair<SourceFileElement*,SourceFileElement*> MatchedFilePair;
		typedef vector<pair<resultStruct,MatchedFilePair> > MatchingType;
		MatchingType matchedFilesList;

		void matchBaseLines();
		int compareFileNames(string file1, string file2);

		struct PreferenceStruct
		{
			SourceFileElement* fileElement;
			int value;
		};

		typedef vector<PreferenceStruct> PreferenceMapType;
		typedef map<SourceFileElement*,PreferenceMapType*> BaselinePreferenceMapType;
		typedef map<SourceFileElement*,SourceFileElement*> BaselineFileMapType;

		//This sorts the preference vector in descending order
		struct CustomCMP
		{
			bool operator() (const PreferenceStruct &a, const PreferenceStruct &b) const
			{                    
				return a.value < b.value;
			};
		};

		void processPairs();
		void printResults();
		void output_intro_hdr_comp();
		void PrintDiffFileResults (string &filename, string &filenameB, resultStruct& myResults, string &lang, bool useDup);
		void PrintDiffResultSummary();
		void PrintMatchedPairs();
		ofstream outfile_diff_results;		// Contains output info
		ofstream outfile_diff_csv;			// Contains output info in CSV format
		ofstream dup_outfile_diff_results;  // Contains duplicate output info
		ofstream dup_outfile_diff_csv;		// Contains duplicate output info in CSV format
		bool printDup;

	public:
		DiffTool();
		~DiffTool(){}
		int DiffToolWrapper(int argc, char *argv[]);
};

#endif
